package cool.doudou.doudada.message.core.helper;

import com.alibaba.fastjson2.JSONObject;
import cool.doudou.doudada.message.core.api.AliApi;
import cool.doudou.doudada.message.core.api.WxApi;
import cool.doudou.doudada.message.core.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * MessageHelper
 *
 * @author jiangcs
 * @since 2022/08/23
 */
@Slf4j
public class MessageHelper {
    private AliApi aliApi;
    private WxApi wxApi;

    /**
     * 阿里云短信消息
     *
     * @param phoneNumbers  接收短信的手机号码，多个以半角逗号（,）分隔
     * @param signName      短信签名名称
     * @param templateCode  短信模板CODE
     * @param templateParam 短信模板变量对应的实际值，JSON格式
     * @param outId         自定义ID，回执消息中会返回此ID
     * @return 发送回执ID
     */
    public String aliSms(String phoneNumbers, String signName, String templateCode, String templateParam, String outId) {
        if (aliApi == null) {
            throw new IllegalArgumentException("阿里云消息配置错误");
        }

        Map<String, String> bizParamMap = new HashMap<>(4);
        bizParamMap.put("PhoneNumbers", phoneNumbers);
        bizParamMap.put("SignName", signName);
        bizParamMap.put("TemplateCode", templateCode);
        bizParamMap.put("TemplateParam", templateParam);
        if (!ObjectUtils.isEmpty(outId)) {
            bizParamMap.put("OutId", outId);
        }
        JSONObject resultObj = aliApi.sms("SendSms", bizParamMap);
        if (!ObjectUtils.isEmpty(resultObj)) {
            if ("OK".equals(resultObj.getString("Code"))) {
                log.info("Sms消息发送成功：" + resultObj.getString("BizId"));

                return resultObj.getString("BizId");
            } else {
                log.error("Sms消息发送失败：" + resultObj.getString("Message"));
            }
        } else {
            log.error("Sms消息发送失败：返回结果为空");
        }
        return null;
    }

    /**
     * 查询 阿里云短信消息
     *
     * @param phoneNumber 接收短信的手机号码
     * @param bizId       发送回执ID
     * @param sendDate    短信发送日期，支持查询最近30天的记录，格式为yyyyMMdd
     * @return 短信发送明细，JSON数组
     */
    public String aliSmsQuery(String phoneNumber, String bizId, String sendDate) {
        if (aliApi == null) {
            throw new IllegalArgumentException("阿里云消息配置错误");
        }

        Map<String, String> bizParamMap = new HashMap<>(5);
        bizParamMap.put("PhoneNumber", phoneNumber);
        bizParamMap.put("BizId", bizId);
        bizParamMap.put("SendDate", sendDate == null ? DateUtil.formatDate(new Date(), "yyyyMMdd") : sendDate);
        bizParamMap.put("PageSize", "50");
        bizParamMap.put("CurrentPage", "1");
        JSONObject resultObj = aliApi.sms("QuerySendDetails", bizParamMap);
        if (!ObjectUtils.isEmpty(resultObj)) {
            if ("OK".equals(resultObj.getString("Code"))) {
                log.info("Sms消息查询成功：" + resultObj.getString("SmsSendDetailDTOs"));

                return resultObj.getString("SmsSendDetailDTOs");
            } else {
                log.error("Sms消息查询失败：" + resultObj.getString("Message"));
            }
        } else {
            log.error("Sms消息查询失败：返回结果为空");
        }
        return null;
    }

    /**
     * 阿里云 发送语音通话
     *
     * @param calledNumber 接收语音通知的手机号码
     * @param ttsCode      文本转语音模板ID
     * @param ttsParam     模板中的变量参数，JSON格式
     * @param outId        自定义ID，回执消息中会返回此ID
     * @return 通话的唯一回执ID
     */
    public String aliVoice(String calledNumber, String ttsCode, String ttsParam, String outId) {
        return aliVoice(calledNumber, ttsCode, ttsParam, null, null, null, outId);
    }

    /**
     * 阿里云 发送语音通话
     *
     * @param calledNumber 接收语音通知的手机号码
     * @param ttsCode      文本转语音模板ID
     * @param ttsParam     模板中的变量参数，JSON格式
     * @param speed        语速控制。取值范围为：-500~500，默认值100
     * @param outId        自定义ID，回执消息中会返回此ID
     * @return 通话的唯一回执ID
     */
    public String aliVoice(String calledNumber, String ttsCode, String ttsParam, Integer speed, String outId) {
        return aliVoice(calledNumber, ttsCode, ttsParam, null, null, speed, outId);
    }

    /**
     * 阿里云 发送语音通话
     *
     * @param calledNumber 接收语音通知的手机号码
     * @param ttsCode      文本转语音模板ID
     * @param ttsParam     模板中的变量参数，JSON格式
     * @param playTimes    一通电话内语音通知内容的播放次数。取值范围：1~3，默认取值3
     * @param speed        语速控制。取值范围为：-500~500，默认值100
     * @param outId        自定义ID，回执消息中会返回此ID
     * @return 通话的唯一回执ID
     */
    public String aliVoice(String calledNumber, String ttsCode, String ttsParam, Integer playTimes, Integer speed, String outId) {
        return aliVoice(calledNumber, ttsCode, ttsParam, playTimes, null, speed, outId);
    }

    /**
     * 阿里云 发送语音通话
     *
     * @param calledNumber 接收语音通知的手机号码
     * @param ttsCode      文本转语音模板ID
     * @param ttsParam     模板中的变量参数，JSON格式
     * @param playTimes    一通电话内语音通知内容的播放次数。取值范围：1~3，默认取值3
     * @param volume       语音通知的播放音量。取值范围：0~100，默认取值100
     * @param speed        语速控制。取值范围为：-500~500，默认值100
     * @param outId        自定义ID，回执消息中会返回此ID
     * @return 通话的唯一回执ID
     */
    public String aliVoice(String calledNumber, String ttsCode, String ttsParam, Integer playTimes, Integer volume, Integer speed, String outId) {
        if (aliApi == null) {
            throw new IllegalArgumentException("阿里云消息配置错误");
        }

        Map<String, String> bizParamMap = new HashMap<>(4);
        bizParamMap.put("CalledNumber", calledNumber);
        bizParamMap.put("TtsCode", ttsCode);
        bizParamMap.put("TtsParam", ttsParam);
        if (!ObjectUtils.isEmpty(playTimes)) {
            bizParamMap.put("PlayTimes", String.valueOf(playTimes));
        }
        if (!ObjectUtils.isEmpty(volume)) {
            bizParamMap.put("Volume", String.valueOf(volume));
        }
        if (!ObjectUtils.isEmpty(speed)) {
            bizParamMap.put("Speed", String.valueOf(speed));
        }
        if (!ObjectUtils.isEmpty(outId)) {
            bizParamMap.put("OutId", outId);
        }
        JSONObject resultObj = aliApi.voice("SingleCallByTts", bizParamMap);
        if (!ObjectUtils.isEmpty(resultObj)) {
            if ("OK".equals(resultObj.getString("Code"))) {
                log.info("Voice消息发送成功：" + resultObj.getString("CallId"));

                return resultObj.getString("CallId");
            } else {
                log.error("Voice消息发送失败：" + resultObj.getString("Message"));
            }
        } else {
            log.error("Voice消息发送失败：返回结果为空");
        }
        return null;
    }

    /**
     * 阿里云 查询语音通话
     *
     * @param callId 通话的唯一识别ID
     * @return 呼叫详情，JSON格式
     */
    public String aliVoiceQuery(String callId) {
        if (aliApi == null) {
            throw new IllegalArgumentException("阿里云消息配置错误");
        }

        Map<String, String> bizParamMap = new HashMap<>(4);
        bizParamMap.put("CallId", callId);
        bizParamMap.put("ProdId", "11000000300006");
        bizParamMap.put("QueryDate", String.valueOf(System.currentTimeMillis()));
        JSONObject resultObj = aliApi.voice("QueryCallDetailByCallId", bizParamMap);
        if (!ObjectUtils.isEmpty(resultObj)) {
            if ("OK".equals(resultObj.getString("Code"))) {
                log.info("Voice消息查询结果：" + resultObj.getString("Data"));

                return resultObj.getString("Data");
            } else {
                log.error("Voice消息查询失败：" + resultObj.getString("Message"));
            }
        } else {
            log.error("Voice消息查询失败：返回结果为空");
        }
        return null;
    }

    /**
     * 微信模版消息
     *
     * @param accessToken  AccessToken
     * @param openId       用户OpenId
     * @param templateId   模版Id
     * @param templateData 模版数据
     * @return true-成功；false-失败
     */
    public boolean wxTemplateMsg(String accessToken, String openId, String templateId, String templateData) {
        if (wxApi == null) {
            throw new IllegalArgumentException("微信消息配置错误");
        }

        // 消息体
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser", openId);
        jsonObject.put("template_id", templateId);
        jsonObject.put("data", JSONObject.parseObject(templateData, JSONObject.class));
        // Url参数
        Map<String, String> urlParam = new HashMap<>(1);
        urlParam.put("access_token", accessToken);
        JSONObject resultObj = wxApi.template(urlParam, jsonObject.toString());
        if (!ObjectUtils.isEmpty(resultObj)) {
            if (0 == resultObj.getIntValue("errcode")) {
                log.info("模板消息发送成功：{}", jsonObject);

                return true;
            } else {
                log.error("模板消息发送失败：" + resultObj.getString("errmsg"));
            }
        } else {
            log.error("模板消息发送失败：返回结果为空");
        }
        return false;
    }

    @Autowired(required = false)
    public void setAliApi(AliApi aliApi) {
        this.aliApi = aliApi;
    }

    @Autowired(required = false)
    public void setWxApi(WxApi wxApi) {
        this.wxApi = wxApi;
    }
}
